home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 13.3 KB | 512 lines | [TEXT/MPS ] |
- %
- % File: FontHandlerProcs.ps
- %
- % Version: Technology: Quickdraw GX 1.1.x.
- %
- % Copyright: © 1991-7 by Apple Computer, Inc., all rights reserved.
- %
- %
- %
- % This file contains PostScript procedures for the font handler
- %
-
- /FHSaveLevel null def
-
- %
- %
- % Procedure DoSave:
- %
- % Procedure saves the current VM sate.
- %
- /DoSave {
-
- /FHSaveLevel save def
-
- } bind def
-
-
- %
- %
- % Procedure DoRestore
- %
- % Procedure restores to the saved VM state.
- % Maintains the current point if there was one.
- /DoRestore {
-
- /currentpoint % Maintain the current-point because IE can't restore it easily.
- load stopped not % There might not be a current point.
-
- dup { % But, if there was, make sure we can keep it the same after the restore.
- % Stack is x y bool
- 3 1 roll % Move the current point to top of stack.
- transform % So transform it to device space since the restore can change the CTM.
- 3 -1 roll % Stack is x' y' bool
-
- } if
-
- FHSaveLevel restore % Do the restore.
-
- { % If there was a current point, it is on stack in device space.
-
- itransform % Put it into space of CTM
- moveto % move there.
-
- } if
-
- } bind def
-
-
-
- %<FF>
- %
- % Routine: HexDigitToInt
- % Routine takes the ascii value of a hex digit (0-9, A-F, a-f) and returns the integer (0-15)
- %
- % ascii-digit HexDigitToInt int
- %
- /HexDigitToInt {
-
- % Stack is next byte of name:
-
- dup 57 le { % If it is less than or equal to '9', must be a 0-9
- 48 sub % subtract 48 (0)
- } { % else
- dup 70 le { % If it is less than or equal to 'F', must be an A-F
- 55 sub % subtract 65 (A) add 10
- } { % else must be a-f
- 87 sub % subtract 97 (a) add 10
- } ifelse
- } ifelse
-
- } bind def
-
- %
- % Routine: HexNameToBytes
- % Routine takes a name that is a string of hex bytes
- % and makes it into a string such that each byte
- % of the string is the converted hex value.
- %
- % /a01AF yields <01AF>
- %
- % name HexNameToBytes string
- %
- /HexNameToBytes {
-
- nameString cvs % Convert the name to a string.
- /nameLength exch length 1 sub def % Store the length of the substring in here. (-1 for leading "a")
- nameString 1 nameLength getinterval % Get the string without the leading "a"
- /tempString exch def % Put it in tempString, processing will be on tempString.
-
- % Loop over the string
- 0 1 nameLength 1 sub { % Loop from zero to length-1
-
- tempString exch get % Get the next digit ou;t of the string.
- HexDigitToInt % Convert the digit to an integer, leave it on the stack.
-
- } for
-
- % Stack is now: digit0, …, digitN
-
- %
- % Now put the bytes for the hex digits back into the string
- %
- nameLength 2 idiv 1 sub -1 0 { % Loop for number of bytes, indexing backwards since digits are on stack
-
- % Stack is: next 2 digits, index
-
- 3 1 roll % Stack is: index, next 2 digits.
- exch 16 mul add % Convert the two digits into a byte.
- % Stack is: index byte
- tempString 3 1 roll
- put % Put the byte into the string at the index position.
-
- } for
-
- tempString 0 nameLength 2 idiv getinterval
-
- } bind def
-
-
- %
- % The BuiildChar procedure for "reencoded" composite fonts:
- % Converts the glyph names into a 1 or 2 byte string to
- % "show" from the base composite font.
- % The glyph names must have been generated from a 'post' table
- % format 4 or this won't work at all.
- %
- /ReEncodedCompositeBuildChar {
-
- GXFontDict begin % This buildchar Uses definitions in here
-
- exch begin
-
- LocalVariables begin
-
- Encoding exch get % Get the name for this character out of encoding.
- baseFontDict setfont % Make the base composite font the current font.
- HexNameToBytes % Convert the name into a string, leave on stack.
-
- dup stringwidth % Get the advance metrics of the character on the stack.
- setcharwidth % Set up the font cache with metrics
- 0 0 moveto show % Actually draw the character.
-
- end
-
- end
-
- end
-
-
- } bind def
-
- %
- %
- % Procedure: ReEncodeCompositeFont
- %
- % Procedure makes a new font that is a re-encoding of a composite font (type-0)
- % In order for this to work, the Encoding vectors must contain names that are the
- % hex strings of the character codes for the glyph in question (preceeded by leading "a") as
- % defined by the 'post' table type 4.
- % For example character code 257 would have name /a0101, character 15 would have name /a0F
- %
- %
- % newName fixSeac encoding fontDict ReEncodeCompositeFont -
- % newName: The name to give the re-encoded font.
- % fixSEAC: Boolean, true if we should fix up the encoding for SEAC characters.
- % encoding: An array containing the encoding vector.
- % fontDict: font dictionary of font to re-encode.
- /ReEncodeCompositeFont {
-
- 10 dict begin
-
- 1 scalefont /baseFontDict exch def % Make a 1 point base font for buildChar.
- /Encoding exch def % Grab the encoding.
- pop % pop off fixSEAC, it means nothing here.
-
- /FontMatrix matrix def
- /FontBBox [0 0 0 0] def
-
- /FontType 3 def
-
- /BuildChar /ReEncodedCompositeBuildChar load def
-
- /LocalVariables 3 dict dup begin
- /nameString 5 string def % 4 bytes allows for 2 byte character codes in hex. (plus one for leading "a")
- /nameLength 0 def % The length of the encoding name will be stored in here.
- /tempString 4 string def % 4 bytes for hex portion of name, also used for show.
- end def
-
-
- currentdict % Leave a copy of the dictionary on the stack for definefont
- end
-
- definefont pop
-
- } bind def
-
-
-
-
- %<FF>
- %
- %
- % Code to deal with SEAC (Standard Encoding Accented Characters) fonts
- % The Problem:
- % Fonts that use SEAC on PS versions <= 49.0 require that any components
- % of an accented character that uses SEAC be in the encoding vector as well
- % as the composite character itself.
- %
- % This code is a heuristic hack!! Unfortunately, there is no other way to deal with it.
- % It depends on the following assumptions:
- %
- % 1. The AccentNames array contains all of the accent characters that may be used by a
- % SEAC font.
- %
- % 2. That the names of glyphs that use SEAC are the names of the indivicual characters
- % combined. For example Ccedilla is the C and the cedilla characters.
- %
- %
- /AccentNames [
-
- (acute)
- (grave)
- (circumflex)
- (cedilla)
- (ring)
- (tilde)
- (dieresis)
- (caron)
-
- ] def
-
- /GlyphNameString 255 string def
- /EncodingIndex 0 def
- /FreeEncodingIndex 0 def
- /FoundName false def
-
- %
- % Function: AddToEncoding
- %
- % Function takes a name on the stack and puts it in an empty spot
- % in the encoding if it isn't there already
- %
- % name AddToEncoding -
- %
- /AddToEncoding {
-
- /EncodingIndex 0 store % Initialize the index.
- /FoundName false store % Initialize this too.
- /FreeEncodingIndex -1 store % Sentinal, uninitialized.
-
- %
- % Search the encoding vector for a match or a free spot.
- %
- Encoding {
-
- % Stack is: name, Encoding-name
-
- dup /.notdef eq { % If we hit a .notdef and index isn't zero, save as an available spot
-
- EncodingIndex 0 ne { % If the index wasn't zero, save this position away as an available spot.
- /FreeEncodingIndex
- EncodingIndex store
- } if
- pop % Pop off the duplicate of the encoding name.
-
- } { % Else See if the name matches
- % Stack is: name, Encoding-name
- 1 index eq { % If they match:
- /FoundName true store % Note that we found match
- exit % Exit the loop
- } if
-
- } ifelse
-
- /EncodingIndex EncodingIndex 1 add store % Increment the index
-
- } forall
-
- FoundName not { % If we didn't find the name, put it in the encoding at the first available spot.
-
- FreeEncodingIndex -1 ne { % If we found a free spot
- Encoding exch FreeEncodingIndex exch put % Put the name in the encoding at the free location.
- } { % else
- (Couldn't find empty spot in encoding) == % Notify this condition.
- } ifelse
-
- } { % Else
-
- pop % pop off the name.
-
- } ifelse
-
- } bind def
-
-
- %
- % EncodeAccentedCharacter:
- % Function checks to see if a glyph name is an accented character
- % If it is it makes sure to add the components to the encoding vector
- % if they are not already there.
- %
- % Precondision, the font dictionary is on the dictionary stack.
- %
- % name EncodeAccentedCharacter -
- %
- /EncodeAccentedCharacter {
-
- GlyphNameString cvs % Convert the glyph name to a string, leave it on the stack.
-
- %
- % Loop through the array of accent names, see if the name is an accented character
- %
-
- AccentNames {
-
- % Stack is now: glyph-name, accent-name
-
- 1 index exch % Stack is now: glyph-name, glyph-name, accent-name
-
- search { % If the glyph name contained the accent name.
- % Stack is now: glyph-name, post, accent-name, pre
- 3 -1 roll % Stack is now: glyph-name, accent-name, pre, post
- length 0 eq { % If the length of the post was zero, then we found an accented character
-
- % Stack is now: glyph-name, accent-name, pre
- cvn exch cvn % Convert those strings to names
- AddToEncoding % The pre string is the character that is accented, add it to the encoding
- AddToEncoding % Add the accent-name to the encoding
- exit % Exit the loop
-
- } { % Else
- pop pop % Pop off the accent-na,e and the pre - not a valid match
- } ifelse
-
- } { % Else
- pop % If no match, pop off the copy of the string left by search
- } ifelse
-
- } forall
-
- pop % Pop off the copy of the glyph name string.
-
- } bind def
-
-
- %
- % Procedure FixSEAC:
- %
- % Procedure takes a font dictionary and resolves any SEAC problems.
- %
- % font-dictionary FixSEAC font-dictionary'
- %
- /FixSEAC {
-
- dup begin % Put the font dictionary on the dict stack
-
- Encoding { % Loop through the encoding vector
-
- EncodeAccentedCharacter % Fix the character.
-
- } forall
-
- end
-
- } bind def
-
-
-
- %<FF>
- %
- % Procedure ReEncodeNormalFont:
- %
- % Procedure Re-encodes a non-coposite font.
- %
- % newName fixSEAC encoding fontName ReEncodeFont -
- %
- % newName: The name to give the re-encoded font.
- % fixSEAC: Boolean, true if we should fix up the encoding for SEAC characters.
- % encoding: An array containing the encoding vector.
- % fontDict: font dictionary of font to re-encode.
- %
- /ReEncodeNormalFont {
-
- dup length % Get the size of the font dictionary.
- dict % Make a dictionary for the new font
-
- %
- % Duplicate all entries from the base font except the FID.
- %
- exch % stick the base font dict on top of operand stack
- {
- exch dup /FID ne % Copy entry if it is not FID.
- {
- 2 index % Copy the new dict to top of operand stack, stack is (dict key val dict)
- 4 1 roll % Make stack (dict dict value key)
- exch
- put % Copy the value, the new dict is still on the stack
- }
- {pop pop} % Don't duplicate the FID
- ifelse
- } forall
-
- % the new dictionary is on the stack.
-
- dup % Stack is: name fixSEAC encoding dict dict
- 3 -1 roll % Stack is: name fixSEAC dict dict encoding
- /Encoding exch % Stack is: name fixSEAC dict dict /Encoding encoding
- put % stack is: name fixSEAC dict
-
- %
- % If we need to fix SEAC, do it
- %
- exch { % if fixSEAC
-
- dup /FontType get 4 eq % If the font type is 4 (font-folio fonts)
- version cvr 49.0 le % if version is <= 49.0, SEAC (bug was fixed after this according to Gayle Tyson @ Adobe)
- or { % If either of the above is true
- FixSEAC % fix SEAC encoding.
- } if
-
- } if
-
- definefont pop
-
- } bind def
-
-
-
- %<FF>
- %
- % Procedure ReEncodeFont:
- %
- % Procedure Re-encodes a non-coposite font.
- %
- % newName fixSEAC encoding fontName ReEncodeFont -
- %
- % newName: The name to give the re-encoded font.
- % fixSEAC: Boolean, true if we should fix up the encoding for SEAC characters.
- % encoding: An array containing the encoding vector.
- % fontName: The name of the font to re-encode.
- %
- /ReEncodeFont {
-
- findfont dup /FontType get 0 eq {
-
- ReEncodeCompositeFont
-
- } {
-
- ReEncodeNormalFont
-
- } ifelse
-
- } bind def
-
-
-
-
-
- %<FF>
- %
- % Procedure MakeCompositeFont
- %
- % Procedure takes an array of font objects and makes a composite font out of them.
- % The resulting font will take 2-byte strings in "show" operations such that the
- % first byte is which font to use and the second byte is which character
- % This will allow creating single fonts with up to 65536 glyphs.
- %
- % fontArray newName MakeCompositeFont -
- %
- /MakeCompositeFont {
-
- 6 dict begin % Make a dictionary for the composite font.
-
- /FontName exch def % Get the name for the composite font.
-
- dup length /numFonts exch def % Cache the number of fonts
-
- /FontType 0 def % Font is type zero.
- /FMapType 2 def % FMapType 2 means first byte is index into Encoding for font, 2nd is character to draw.
- /FDepVector exch def % The array of fonts passed in is the FDepVector.
-
- /FontMatrix matrix def % The Font matrix is identity, base fonts have real information.
-
- % Create the encoding which is just an array with elements as integers 0 to N-1 where N is # of fonts in FDepVector
- % example: [0 1 2 3] for 4 fonts.
-
- /Encoding numFonts array def
-
- 0 1 numFonts 1 sub {
-
- Encoding exch dup % Stack is: Encoding index index
- put % Put index into encoding at position index.
-
- } for
-
- FontName currentdict definefont pop
-
- end
-
- } bind def
-